package main

import (
	"context"
	"fmt"
	"github.com/coreos/etcd/clientv3"
	"log"
	"time"
)

//监听etcd中的k v变化，用op代替get,put，del，Txn.分布式锁必须用到的操作,貌似无法watch了？watch只针对put和delete
func main() {

	var (
		clientV3Conf clientv3.Config

		opResponse clientv3.OpResponse
	)

	clientV3Conf = clientv3.Config{
		Endpoints:   []string{"10.70.30.73:2379"},
		DialTimeout: 3 * time.Second,
	}
	cli, err := clientv3.New(clientV3Conf)
	if err != nil {
		log.Fatal(err)
	}
	defer cli.Close()

	time.Sleep(1 * time.Microsecond)
	ops := []clientv3.Op{
		clientv3.OpPut("put-key-", "123"),
		//clientv3.OpGet("put-key"),
		clientv3.OpPut("put-key-", "456"),
	}

	for _, op := range ops {
		if opResponse, err = cli.Do(context.TODO(), op); err != nil {
			log.Fatal(err)
		}
		fmt.Println("put 第一次revision 是", opResponse.Put().Header.GetRevision())

		//fmt.Println("put 第一次之前的value 是", opResponse.Put().PrevKv.Value)
		//fmt.Println(opResponse)
	}
	getOp := clientv3.OpGet("put-key-")
	opResponse, _ = cli.Do(context.TODO(), getOp)
	fmt.Println("get 的value 是", string(opResponse.Get().Kvs[0].Value))

	////监听
	//watchChannels = cli.Watch(context.TODO(), "put-key")
	////channel中有kv变化的时候，会将response投递到channel中 ，遍历即可
	//for watchResponseFromChan = range watchChannels {
	//	//events 是mvccpb.Event数组，事件类型为put 和delete，包括put为新的kv，以及覆盖掉的preKV。这里可以再回头看看createRevision,ModRevision相关。如果是删除操作，此时create_revision归0，后续再创建，create_version 为mod_creation+1。注意这个events可能有其他key的变化，取决你watch的参数
	//	for _, ev := range watchResponseFromChan.Events {
	//		//解析方法1
	//		fmt.Printf("===开始监听,事件类型为:%s。 key为%q : value为%q,创建revision为%d,修改revision为%d\n", ev.Type, ev.Kv.Key, ev.Kv.Value, ev.Kv.CreateRevision, ev.Kv.ModRevision)
	//		////	解析event方法2
	//		//switch ev.Type {
	//		//case mvccpb.PUT:
	//		//	fmt.Printf("=====%s事件,key为%q,value为%q,创建Create revision为%d,修改Mod revision为%d\n", ev.Type, ev.Kv.Key, ev.Kv.Value, ev.Kv.CreateRevision, ev.Kv.ModRevision)
	//		//
	//		//case mvccpb.DELETE:
	//		//	fmt.Printf("=====%s事件,key为%q,value为%q,[注意]创建Create revision为%d,修改 Mod revision为%d\n", ev.Type, ev.Kv.Key, ev.Kv.Value, ev.Kv.CreateRevision, ev.Kv.ModRevision)
	//		//}
	//	}
	//}

}
